/* ========================================================================= */
/* ------------------------------------------------------------------------- */
/*!
  \file			ETSheet.cc
  \date			september 2011
  \author		TNick

  \brief		Contains the implementation for ETSheet class


  Copyright (c) 2011, Nicu Tofan
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
 * Neither the name of the copyright holder nor the
   names of its contributors may be used to endorse or promote products
   derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. IN NO EVENT SHALL NICU TOFAN BE LIABLE FOR ANY
 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
//
//
//
//
/*  INCLUDES    ------------------------------------------------------------ */

#include	<main.h>

#include	<QDomDocument>
#include	<QMessageBox>
#include	<QApplication>

#include	<gui/mainwindow.h>
#include	<gui/mdichild.h>

#include	<sheet/ETI_CplxTxt.h>
#include	<sheet/ETI_MTxt.h>
#include	<sheet/ETSheetView.h>

#include	"ETSheet.h"

/*  INCLUDES    ============================================================ */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */
DDHC_CONTENT(ETSheet)
QList<ETSheet*>		ETSheet::invisible_list;


/* ------------------------------------------------------------------------- */
ETSheet::ETSheet	(QObject * parent)
	: QGraphicsScene (parent),
	  hd_ur(this)
{
	DDHC_CONSTRUCT;
	DDHC_VARIABLE(back_col);
	//    DDHC_NODE(&cl_inst);
	//    DDHC_NODE(&cl_another_inst);
	DDHC_VARIABLE(vp_crt);
	//	DDHC_VARIABLE(&hd_ur);
	DDHC_VARIABLE(mdi_cont);



	vp_crt = NULL;
	mdi_cont = NULL;
	back_col = QColor(Qt::yellow);

}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
ETSheet::~ETSheet	( void )
{
	if (mdi_cont != NULL)
	{
		MdiChild * tmp = mdi_cont;
		mdi_cont = NULL;
		tmp->close();
		tmp->deleteLater();
	}
	else
	{
		int i = invisible_list.indexOf(this);
		if (i >= 0)
		{
			invisible_list.removeAt(i);
		}
	}

	DDHC_DESTRUCT
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
ETSheet *		ETSheet::newInvisible			(
	QString s_file, QString * s_err	)
{
	s_err->clear();
	ETSheet * new_sht = new ETSheet();

	if (!s_file.isEmpty())
	{
		new_sht->loadXMLFile(s_file);
	}

	invisible_list.append(new_sht);
	return new_sht;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
ETSheet *		ETSheet::newVisible				(
	QString s_file, MdiChild * asoc_w)
{
	QApplication::setOverrideCursor(Qt::WaitCursor);

	ETSheet * new_sht = new ETSheet();
	new_sht->mdi_cont = asoc_w;

	if (!s_file.isEmpty())
	{
		new_sht->loadXMLFile(s_file);
	}
	else
	{
		new_sht->vp_crt = new ETSheetView(new_sht, new_sht->mdi_cont);
		new_sht->mdi_cont->setWidget(new_sht->vp_crt);
	}

	QApplication::restoreOverrideCursor();
	return new_sht;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
int				ETSheet::visibleCount			( void )
{
	return g_MW->docsOpened();
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
ETSheet *		ETSheet::visibleDoc				(int doc_index)
{
	MdiChild * mdi_kid = g_MW->docByIndex(doc_index);
	if (mdi_kid == NULL)
		return NULL;
	return mdi_kid->assocDoc();
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
ETI_CplxTxt *	ETSheet::addBasicCplx			(qreal new_x, qreal new_y)
{
	ETI_CplxTxt * new_ct = new ETI_CplxTxt(this, new_x, new_y);


	return new_ct;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
ETI_CplxTxt *	ETSheet::addCplx1Eq1			(qreal new_x, qreal new_y)
{
	ETI_CplxTxt * new_ct = new ETI_CplxTxt(this, new_x, new_y);

	return new_ct;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
ETI_MTxt *		ETSheet::addMText				(qreal new_x, qreal new_y)
{
	ETI_MTxt * new_mt = new ETI_MTxt();
	addItem(new_mt);
	new_mt->setPos(new_x, new_y);

	return new_mt;
}
/* ========================================================================= */


/* ------------------------------------------------------------------------- */
QDomDocument *	ETSheet::openXMLFile			(QString str_file_trg)
{
	if (str_file_trg.isEmpty())
	{
		QMessageBox::critical(
					g_MW,
					QObject::tr("File error!!!"),
					QObject::tr("No source file was specified.")
					);
		return NULL;
	}


	QFile xml_file(str_file_trg);
	if (!xml_file.exists())
	{
		QMessageBox::critical(
					g_MW,
					QObject::tr("File error!!!"),
					QObject::tr("The file %1 does not exists.")
					.arg(str_file_trg)
					);
		return NULL;
	}

	int errorLine, errorColumn;
	QString errorMsg;
	QDomDocument * doc_ret = new QDomDocument();
	if (!doc_ret->setContent(&xml_file, &errorMsg, &errorLine, &errorColumn))
	{
		QMessageBox::critical(
					g_MW,
					QObject::tr("File error!!!"),
					QObject::tr("Syntax error in file %4, line %1, column %2:\n%3")
					.arg(errorLine)
					.arg(errorColumn)
					.arg(errorMsg)
					.arg(str_file_trg)
					);
		delete doc_ret;
		return NULL;
	}


	QDomElement rootElement = doc_ret->documentElement();
	//	if (rootElement.nodeType() != QDomNode::TextNode)
	//	{
	//		QMessageBox::critical(
	//					g_MW,
	//					QObject::tr("XML file error!!!"),
	//					QObject::tr("The file %1 does not have proper format (%2).")
	//					.arg(str_file_trg)
	//					.arg(tr("root"))
	//					);
	//		delete doc_ret;
	//		return NULL;
	//	}
	if (rootElement.tagName() != QString(XML_TAG_ROOT))
	{
		QMessageBox::critical(
					g_MW,
					QObject::tr("XML file error!!!"),
					QObject::tr("The file %1 does not have proper format (%2).")
					.arg(str_file_trg)
					.arg(tr("marker"))
					);
		delete doc_ret;
		return NULL;
	}

	return doc_ret;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::loadXMLFile			(QString str_file_trg)
{

	/* open the thing and get the root element */
	QDomDocument *	d_xml = openXMLFile(str_file_trg);
	if (d_xml == NULL)
		return;
	/* the element was already checked by the openXMLFile() */
	QDomElement rootElement = d_xml->documentElement();

	QDomElement list;
	QDomElement li_it;

	/* get the list of viewports */
	list = rootElement.firstChildElement(XML_TAG_VP_LIST);
	if (!list.isNull())
	{
		ETSheetView::loadXML(this, assocMDI(), list);
	}
	else
	{
		vp_crt = new ETSheetView(this, mdi_cont);
		mdi_cont->setWidget(vp_crt);
	}

	/* get the list of complex texts items */
	list = rootElement.firstChildElement(XML_TAG_CPLX_LIST);
	if (!list.isNull())
	{
		/* iterate in items */
		li_it = list.firstChildElement(XML_TAG_ITEM);
		while (!li_it.isNull())
		{
			ETI_CplxTxt::loadXML(this, li_it);
			li_it = li_it.nextSiblingElement(XML_TAG_ITEM);
		}
	}

	/* get the list of formatted texts items */
	list = rootElement.firstChildElement(XML_TAG_FORM_LIST);
	if (!list.isNull())
	{
		/* iterate in items */
		li_it = list.firstChildElement(XML_TAG_ITEM);
		while (!li_it.isNull())
		{
			ETI_MTxt::loadXML(this, li_it);
			li_it = li_it.nextSiblingElement(XML_TAG_ITEM);
		}
	}

}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::saveXMLFile			(QString str_file_trg)
{
	QFile file( str_file_trg );
	if( file.open( QFile::WriteOnly ) )
	{
		QDomDocument doc_xml(XML_TAG_ROOT);

		QDomElement root = doc_xml.createElement(XML_TAG_ROOT);
		doc_xml.appendChild(root);

		QDomElement list;

		/* the list of viewports */
		list = doc_xml.createElement(XML_TAG_VP_LIST);
		root.appendChild(list);
		ETSheetView::saveXML(this, list);

		/* the list of items */
		QDomElement list_cplx = doc_xml.createElement(XML_TAG_CPLX_LIST);
		root.appendChild(list_cplx);
		QDomElement list_mtxt = doc_xml.createElement(XML_TAG_FORM_LIST);
		root.appendChild(list_mtxt);
		QDomElement list_it;

		QList<QGraphicsItem *>	it_l = items();
		foreach (QGraphicsItem * iter_i, it_l) {
			if (iter_i->type() == ETI_CplxTxt::Type)
			{
				list_it = doc_xml.createElement(XML_TAG_ITEM);
				list_cplx.appendChild(list_it);
				static_cast<ETI_CplxTxt*>(iter_i)->saveXML(list_it);
			}
			else if (iter_i->type() == ETI_MTxt::Type)
			{
				list_it = doc_xml.createElement(XML_TAG_ITEM);
				list_mtxt.appendChild(list_it);
				static_cast<ETI_CplxTxt*>(iter_i)->saveXML(list_it);
			}
			else
			{
				qDebug() << "An item was found in scene that match no "
						 << "type that we know of and will not be saved";
				qDebug() << "The item: " << iter_i;
			}
		}


		QTextStream out(&file);
		QApplication::setOverrideCursor(Qt::WaitCursor);
		out << doc_xml.toString();
		QApplication::restoreOverrideCursor();

	}
	else
	{
		QMessageBox::critical(
					g_MW,
					QObject::tr("XML file error!!!"),
					QObject::tr("The file %1 Could not be created / opened.")
					.arg(str_file_trg)
					);
	}
}
/* ========================================================================= */


/* ------------------------------------------------------------------------- */
void				ETSheet::loadQICommon		(
	QGraphicsItem * dest, QDomElement dom_e )
{
	/* we are provided by the caller with the "common" element */
	QDomElement dom_it;
	QDomElement dom_sit;
	bool b_ok = false;

	/* the position */
	dom_it = dom_e.firstChildElement(XML_TAG_POS);
	if (!dom_it.isNull())
	{


		/* set the placement of this item inside the scene */
		QPointF new_pos(0, 0);
		for (;;)
		{
			/* x component */
			dom_sit = dom_it.firstChildElement(XML_TAG_X);
			if (!dom_sit.isNull())
			{
				new_pos.setX(dom_sit.text().toDouble(&b_ok));
				if (!b_ok)
				{
					qDebug() << "The input presented an X component ("
							 << dom_sit.text() << ") but it could not be "
							 << "parsed into a valid real number.";
					break;
				}

				if (!dom_it.nextSiblingElement(XML_TAG_X).isNull())
				{
					qDebug() << "The input presented more than one "
							 << XML_TAG_X << " tags, when only "
							 << "one per ETI_CplxTxt element is allowed";
				}
			}


			/* y component */
			dom_sit = dom_it.firstChildElement(XML_TAG_Y);
			if (!dom_sit.isNull())
			{

				new_pos.setY(dom_sit.text().toDouble(&b_ok));
				if (!b_ok)
				{
					qDebug() << "The input presented an Y component ("
							 << dom_sit.text() << ") but it could not be "
							 << "parsed into a valid real number.";
					new_pos.setX(0.0);
					break;
				}

				if (!dom_it.nextSiblingElement(XML_TAG_Y).isNull())
				{
					qDebug() << "The input presented more than one "
							 << XML_TAG_Y << " tags, when only "
							 << "one per ETI_CplxTxt element is allowed";
				}
			}

			break;
		}
		dest->setPos(new_pos);



		/* check for other "position" tags */
		if (!dom_it.nextSiblingElement(XML_TAG_POS).isNull())
		{
			qDebug() << "The input presented more than one "
					 << XML_TAG_POS << " tags, when only "
					 << "one per ETI_CplxTxt element is allowed";
		}
	}


}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::saveQICommon		(
	QGraphicsItem * dest, QDomElement dom_e )
{

	/*		position */
	QDomElement dom_it2 = dom_e.ownerDocument().createElement(XML_TAG_POS);
	dom_e.appendChild(dom_it2);

	/*			X */
	QDomElement dom_it3 = dom_e.ownerDocument().createElement(XML_TAG_X);
	dom_it2.appendChild(dom_it3);
	QDomText dom_tx = dom_e.ownerDocument()
			.createTextNode(QString("%1").arg(dest->pos().x()));
	dom_it3.appendChild(dom_tx);

	/*			Y */
	dom_it3 = dom_e.ownerDocument().createElement(XML_TAG_Y);
	dom_it2.appendChild(dom_it3);
	dom_tx = dom_e.ownerDocument()
			.createTextNode(QString("%1").arg(dest->pos().y()));
	dom_it3.appendChild(dom_tx);

}
/* ========================================================================= */


/* ------------------------------------------------------------------------- */
void				ETSheet::vp_DelAll				( void )
{
	if (vp_crt != NULL)
	{
		if (vp_crt->parent() == this)
		{ /* top level */
			QMessageBox::warning(assocMDI(), tr("Error"),
								 tr("No split to delete"));
			return;
		}

		vp_crt->setParent(assocMDI());
		assocMDI()->widget()->close();
		assocMDI()->widget()->deleteLater();
		assocMDI()->setWidget(vp_crt);
		vp_crt->show();
	}
}
/* ========================================================================= */


/* ------------------------------------------------------------------------- */
void				ETSheet::vp_ZoomIn				( void )
{
	if (vp_crt != NULL)
	{
		vp_crt->zoomIn();
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::vp_ZoomOut				( void )
{
	if (vp_crt != NULL)
	{
		vp_crt->zoomOut();
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::vp_RotClk				( void )
{
	if (vp_crt != NULL)
	{
		vp_crt->rotateRight();
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::vp_RotCtrClk				( void )
{
	if (vp_crt != NULL)
	{
		vp_crt->rotateLeft();
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
QWidget *			ETSheet::vp_TopWidget				(bool * b_is_viewport)
{
	if (mdi_cont == NULL)
		return NULL;

	/* if there is a splitter then it's top level */
	QSplitter * splt = mdi_cont->findChild<QSplitter *>();
	if (splt == NULL)
	{
		*b_is_viewport = true;
		return mdi_cont->findChild<QGraphicsView *>();
	}
	*b_is_viewport = false;
	return splt;

}
/* ========================================================================= */


/* ------------------------------------------------------------------------- */
void				ETSheet::setCurrentVp				( ETSheetView * new_vp )
{
	if (mdi_cont == NULL)
		return;

	if (vp_crt != NULL)
	{
		ETSheetView * old = vp_crt;
		vp_crt = NULL;
		old->resetCachedContent();
	}
	vp_crt = new_vp;
	if (vp_crt != NULL)
	{
		vp_crt->resetCachedContent();
	}

}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::setBackground				(QColor new_col)
{
	back_col = new_col;
	if (vp_crt != NULL)
	{
		vp_crt->update();
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::vp_ZoomExt					( void )
{
	if (vp_crt != NULL)
	{
		vp_crt->vp_ZoomExt();
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::vp_ZoomWin					( void )
{
	if (vp_crt != NULL)
	{
		ETVpCmd_ZoomWin::go(vp_crt);
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::changeBackCol				( void )
{
	if ((vp_crt != NULL))
	{
		changeBackCol(vp_crt->currentSubI());
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::changeForeCol				( void )
{
	if ((vp_crt != NULL))
	{
		changeForeCol(vp_crt->currentSubI());
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::changeFont					( void )
{
	if ((vp_crt != NULL))
	{
		changeFont(vp_crt->currentSubI());
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::incFontSize				( void )
{
	if ((vp_crt != NULL))
	{
		incFontSize(vp_crt->currentSubI());
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::decFontSize				( void )
{
	if ((vp_crt != NULL))
	{
		decFontSize(vp_crt->currentSubI());
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::clearFormat				( void )
{
	if ((vp_crt != NULL))
	{
		clearFormat(vp_crt->currentSubI());
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::changeBackCol				( ETSubItem * s_it )
{
	if (s_it != NULL)
	{

	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::changeForeCol				( ETSubItem * s_it  )
{
	if (s_it != NULL)
	{

	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::changeFont					( ETSubItem * s_it  )
{
	if (s_it != NULL)
	{

	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::incFontSize				( ETSubItem * s_it  )
{
	if (s_it != NULL)
	{

	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::decFontSize				( ETSubItem * s_it  )
{
	if (s_it != NULL)
	{

	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::clearFormat				( ETSubItem * s_it  )
{
	if (s_it != NULL)
	{

	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::changeBackCol				( ETI_CplxTxt * it )
{
	if ((it != NULL))
	{
		changeBackCol(it->rootSI());
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::changeForeCol				( ETI_CplxTxt * it )
{
	if ((it != NULL))
	{
		changeForeCol(it->rootSI());
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::changeFont					( ETI_CplxTxt * it )
{
	if ((it != NULL))
	{
		changeFont(it->rootSI());
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::incFontSize				( ETI_CplxTxt * it )
{
	if ((it != NULL))
	{
		incFontSize(it->rootSI());
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::decFontSize				( ETI_CplxTxt * it )
{
	if ((it != NULL))
	{
		decFontSize(it->rootSI());
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				ETSheet::clearFormat				( ETI_CplxTxt * it  )
{
	if ((it != NULL))
	{
		clearFormat(it->rootSI());
	}
}
/* ========================================================================= */



/*  CLASS    =============================================================== */
//
//
//
//
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
